#include "node.h"
#include "namespace.h"
#include "type.h"

Node::Node()
{
    m_parentNode = 0;
    m_nextSibling = 0;
    m_previousSibling = 0;
}

Node::Node( const YYLTYPE& loc )
        : m_loc(loc)
{
    m_parentNode = 0;
    m_nextSibling = 0;
    m_previousSibling = 0;
}

void Node::insertBefore( Node* child, Node* before )
{
    if ( !before )
        this->appendChild(child);
    else
    {
        int index = this->m_children.indexOf(before);
        Q_ASSERT( index != -1 );
        if ( child->parentNode() )
            child->parentNode()->removeChild( child );
        this->m_children.insert( index, child );
        child->m_parentNode = this;
        child->m_previousSibling = before->previousSibling();
        child->m_nextSibling = before;
        if ( before->m_previousSibling )
            before->m_previousSibling->m_nextSibling = child;
        before->m_previousSibling = child;
    }
}

void Node::appendChild( Node* child )
{
    Node* last = this->lastChild();
    if ( child->parentNode() )
        child->parentNode()->removeChild( child );
    this->m_children.append(child);
    child->m_parentNode = this;
    child->m_nextSibling = 0;
    child->m_previousSibling = last;
    if ( last )
        last->m_nextSibling = child;
}

void Node::removeChild( Node* child )
{
    bool ok = this->m_children.removeOne(child);
    Q_ASSERT(ok);
    child->m_parentNode = 0;
    child->m_nextSibling = 0;
    child->m_previousSibling = 0;
}

Namespace* Node::nspace() const
{
    Node* n = (Node*)this;
    while( n )
    {
        Namespace* ns = dynamic_cast<Namespace*>(n);
        if ( ns )
            return ns;
        n = n->parentNode();
    }
    return 0;
}

void Node::resolveAll()
{
    Node* n = this->firstChild();
    while( n )
    {
        n->resolveAll();
        n = n->nextSibling();
    }
}

void Node::includeLocation(const YYLTYPE& loc)
{
    if ( loc.first_line < m_loc.first_line )
    {
        m_loc.first_line = loc.first_line;
        m_loc.first_column = loc.first_column;
    }
    else if ( loc.first_line == m_loc.first_line && loc.first_column < m_loc.first_column )
        m_loc.first_column = loc.first_column;

    if ( loc.last_line > m_loc.last_line )
    {
        m_loc.last_line = loc.last_line;
        m_loc.last_column = loc.last_column;
    }
    else if ( loc.last_line == m_loc.last_line && loc.last_column > m_loc.last_column )
        m_loc.last_column = loc.last_column;
}

Type Node::type()
{
    return Type();
}
